package slw.controls
{
	import flash.display.DisplayObject;
	import flash.display.GradientType;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.utils.getDefinitionByName;
	
	import slw.core.UIComponent;
	import slw.events.LoaderEvent;
	
	
	/**
	 * BaseButton
	 * 按钮基类，无文本，支持4帧影片皮肤，4元素数组皮肤，4元素图片url皮肤
	 * @author ddx<br/>
	 * 2011-7-21
	 *
	 */
	public class BaseButton extends UIComponent
	{
		/**
		 *  "up",鼠标弹起状态
		 */		
		public static const UP:String="up";
		/**
		 *  "over",鼠标经过状态
		 */		
		public static const OVER:String="over";
		/**
		 *  "down",鼠标按下状态
		 */
		public static const DOWN:String="down";
		/**
		 *  "disabled",禁用状态
		 */
		public static const DISABLED:String="disabled";
		//状态显示对象数组，状态显示对象数组，状态显示对象字符串数组
		private var _displayStates:Array=[];
		private var _displayStateStrs:Array=[];
		private var _defaultDisplayStates:Array=[];
		//当前状态
		private var _state:String=UP;
		
		//状态容器，遮罩
		private var _stateContainer:Sprite;
		/**
		 * 构造函数 
		 * @param displayStates:Array=null 显示对象状态数组，0-4索引处的元素将作为按钮4种状态显示
		 * 
		 */		
		public function BaseButton(displayStates:Array=null)
		{
			super();
			this.listName="ButtonBase";
			
			init();
			
			setSize(100,22);
			
			if(displayStates==null){
				_defaultDisplayStates=buildDefaultStates();
				this.displayStates=_defaultDisplayStates;
			}
			this.round=6;
		}
		
		/*
		-----------------------------------
		setters getters
		-----------------------------------
		*/
		//
		/**
		 * 显示对象状态数组，数组元素应为显示对象或类字符串如:[mc1,mc2,mc3,mc4],["mc1","mc2","mc3","mc4"]，0-4索引处的元素或其实例将作为按钮4种状态显示，若数组长度大于4将被截断，默认值:[]
		 * @param value:Array
		 * 
		 */		
		public function set displayStates(value:Array):void{
			if(_displayStates==value)return;
			
			if(value!=null&&value.length!=0){
				if(value[0]!=null&&value[0] is String){
					if(_displayStateStrs==value){
						return;
					}else{
						_displayStateStrs=value;
						_displayStateStrs.length=Math.min(_displayStateStrs.length,4);
						
						_displayStates=[];
						var $c:Class;
						var $instance:*;
						for(var i:int=0;i<value.length;i++){
							$c=getDefinitionByName(value[i]) as Class;
							$instance=new $c();
							_displayStates.push($instance);
						}
					}
				}else{
					_displayStates=value;
				}
			}else{
				_displayStates=value;
			}
			
			
			if(_displayStates!=null&&_displayStates.length!=0&&_stateContainer==null){
				_stateContainer=new Sprite();
				this.buildContainer.addChild(_stateContainer);
			}else if((_displayStates==null||_displayStates.length==0)&&_stateContainer!=null){
				this.buildContainer.removeChild(_stateContainer);
				_stateContainer=null;
			}
			
			if(_displayStates!=null&&_displayStates.length!=0){
				_displayStates.length=Math.min(_displayStates.length,4);
			}
				
			setState(_state);
		}
		//
		/**
		 * 显示对象状态数组，数组元素应为显示对象或类字符串如:[mc1,mc2,mc3,mc4],["mc1","mc2","mc3","mc4"]，0-4索引处的元素或其实例将作为按钮4种状态显示，若数组长度大于4将被截断，默认值:[]
		 * @param value:Array
		 * 
		 */	
		public function get displayStates():Array{
			return _displayStates;
		}
		//
		/**
		 * 组件皮肤数组,数组元素为可视对象的类字符串(如:["Skin1","Skin2"]),皮肤将以其在数组中的顺序进行堆放,索引0处的皮肤位于最底层,
		 * 将skin设置为[]或null清除皮肤
		 * @param value:Array
		 * 
		 */		
		override public function set skin(value:Array):void{
			if(this.skin==value){
				return;
			}
			super.skin=value;
			
			setState(_state);
		}
		//
		/**
		 * 外部皮肤url数组，0-4索引处元素的根显示对象将作为按钮4种状态显示
		 * @param value:Array
		 * 
		 */		
		override public function set displayURLs(value:Array):void{
			if(this.displayURLs==value)return;
			
			this.addEventListener(LoaderEvent.LOAD_COMPLETE,thisLoadComplete);
			super.displayURLs=value;
		}
		//
		/**
		 * 组件是否激活,默认值 true(激活)
		 * @param value:Boolean
		 * 
		 */		
		override public function set enabled(value:Boolean):void{
			if(this.enabled==value){
				return;
			}
			super.enabled=value;
			
			if(this.enabled){
				setState(UP);
			}else{
				setState(DISABLED);
			}
		}
		//
		/**
		 * 圆角大小,默认值:0px 
		 * @param value:Number
		 * 
		 */		
		override public function set round(value:Number):void{
			if(this.round==value)return;
			
			super.round=value;
			
			updateDefaultStates();
		}
		//
		/**
		 * 设置按钮状态，默认值:ButtonBase.UP，可能的值:<br/>
		 * <ul>
		 * <li>ButtonBase.UP 鼠标弹起状态<br/>
		 * <li>ButtonBase.OVER 鼠标经过状态<br/>
		 * <li>ButtonBase.DOWN 鼠标按下状态<br/>
		 * <li>ButtonBase.DISABLED 禁用状态<br/> 
		 * </ul>
		 * @param state:String
		 * 
		 */		
		public function set state(value:String):void{
			if(_state==value) return;
			
			_state=value;
			setState(_state);
		}
		//
		/**
		 * 设置按钮状态，默认值:ButtonBase.UP，可能的值:<br/>
		 * <ul>
		 * <li>ButtonBase.UP 鼠标弹起状态<br/>
		 * <li>ButtonBase.OVER 鼠标经过状态<br/>
		 * <li>ButtonBase.DOWN 鼠标按下状态<br/>
		 * <li>ButtonBase.DISABLED 禁用状态<br/> 
		 * </ul>
		 * @param state:String
		 * 
		 */
		public function get state():String{
			return _state;
		}
		//
		override public function set width(value:Number):void{
			if(this.width==value) return;
			
			super.width=value;
			
			updateDefaultStates();
			setState(_state);
		}
		//
		override public function set height(value:Number):void{
			if(this.height==value) return;
			
			super.height=value;
			
			updateDefaultStates();
			setState(_state);
		}
		//
		protected function get stateContainer():DisplayObject{
			return _stateContainer;
		}
		/*
		-----------------------------------
		public  methods
		-----------------------------------
		*/
		//
		/**
		 * 设置按钮状态，默认值:ButtonBase.UP，可能的值:<br/>
		 * <ul>
		 * <li>ButtonBase.UP 鼠标弹起状态<br/>
		 * <li>ButtonBase.OVER 鼠标经过状态<br/>
		 * <li>ButtonBase.DOWN 鼠标按下状态<br/>
		 * <li>ButtonBase.DISABLED 禁用状态<br/> 
		 * </ul>
		 * @param state:String
		 * 
		 */		
		public function setState(state:String):void{
			var $states:Array=[UP,OVER,DOWN,DISABLED];
			if($states.indexOf(state)==-1)
				throw new Error("按钮状态应为以下值之一:["+$states+"].");
			
			showState($states.indexOf(state));
		}
		//
		override public function destroy():void{
			this.removeEventListener(LoaderEvent.LOAD_COMPLETE,thisLoadComplete);
			removeListeners();
			super.destroy();
		}
		/*
		-----------------------------------
		protected  methods
		-----------------------------------
		*/
		//显示状态
		protected function showState(index:int):void{
			var $skins:Array=this.skinTargets;
			for(var i:int=0;i<$skins.length;i++){
				if($skins[i] is MovieClip)
					MovieClip($skins[i]).gotoAndStop(index+1);
				
				if(this.autoSizeBySkin){
					this.width=MovieClip($skins[i]).width;
					this.height=MovieClip($skins[i]).height;
				}else{
					MovieClip($skins[i]).width=this.width;
					MovieClip($skins[i]).height=this.height;
				}
			}
			
			if(_stateContainer!=null){
				while(_stateContainer.numChildren>0){
					_stateContainer.removeChildAt(0);
				}
				if(_displayStates!=null&&_displayStates[index]!=null)
					_stateContainer.addChild(_displayStates[index]);
				
				if(this.autoSizeBySkin){
					this.width=_stateContainer.width;
					this.height=_stateContainer.height;
				}else{
					_stateContainer.getChildAt(0).width=this.width;
					_stateContainer.getChildAt(0).height=this.height;
				}
			}
		}
		/*
		-----------------------------------
		private  methods
		-----------------------------------
		*/
		//初始化
		private function init():void{
			this.mouseChildren=false;
			
			addListeners();
		}
		//添加侦听
		private function addListeners():void{
			this.addEventListener(MouseEvent.MOUSE_OUT,thisMouseOut);
			this.addEventListener(MouseEvent.MOUSE_OVER,thisMouseOver);
			this.addEventListener(MouseEvent.MOUSE_UP,thisMouseUp);
			this.addEventListener(MouseEvent.MOUSE_DOWN,thisMouseDown);
		}
		//删除侦听
		private function removeListeners():void{
			this.removeEventListener(MouseEvent.MOUSE_OUT,thisMouseOut);
			this.removeEventListener(MouseEvent.MOUSE_OVER,thisMouseOver);
			this.removeEventListener(MouseEvent.MOUSE_UP,thisMouseUp);
			this.removeEventListener(MouseEvent.MOUSE_DOWN,thisMouseDown);
		}
		//创建默认皮肤
		private function buildDefaultStates():Array{
			var $states:Array=[];
			var $borderColors:Array=[0x999999,0x0099CC,0x009999,0x999999];
			var $colors:Array=[[0xeeeeee,0xcccccc],[0xeeeeee,0x85C9E0],[0x85C9E0,0xeeeeee],[0xcccccc,0xeeeeee]];
			for(var i:int=0;i<4;i++){
				$states.push(getState($borderColors[i],$colors[i],this.width,this.height,this.round));
			}
			
			return $states;
		}
		//绘制状态
		private function getState(borderColor:uint,colors:Array,width:Number,height:Number,round:Number):DisplayObject{
			var $m:Matrix=new Matrix();
			$m.createGradientBox(width,height,Math.PI/2);
			
			var $s:Shape=new Shape();
			$s.graphics.lineStyle(0,borderColor,1,true,"none","round");
			$s.graphics.beginGradientFill(GradientType.LINEAR,colors,[1,1],[0,0xff],$m);
			$s.graphics.drawRoundRect(0,0,width,height,round,round);
			$s.graphics.endFill();
			
			return $s;
		}
		//更新默认皮肤
		private function updateDefaultStates():void{
			if(_displayStates==_defaultDisplayStates){
				_defaultDisplayStates=buildDefaultStates();
				this.displayStates=_defaultDisplayStates;
			}
		}
		//鼠标经过
		private function thisMouseOver(e:MouseEvent):void{
			if(_state==OVER)return;
			
			_state=OVER;
			setState(_state);
		}
		//鼠标移出
		private function thisMouseOut(e:MouseEvent):void{
			if(_state==UP)return;
			
			_state=UP;
			setState(_state);
		}
		//鼠标弹起
		private function thisMouseUp(e:MouseEvent):void{
			thisMouseOver(e);
		}
		//鼠标按下
		private function thisMouseDown(e:MouseEvent):void{
			if(_state==DOWN)return;
			
			_state=DOWN;
			setState(_state);
		}
		//加载外部皮肤完成
		private function thisLoadComplete(e:LoaderEvent):void{
			this.displayStates=e.datas;
			
			this.removeEventListener(LoaderEvent.LOAD_COMPLETE,thisLoadComplete);
		}
		//绘制矩形
		private function drawRect(target:*,thickness:Number=0,color:uint=0,alpha:Number=1,x:Number=0,y:Number=0,width:Number=1,height:Number=1,round:Number=0,filled:Boolean=false):void{
			if((target as Sprite)==null&&(target as Shape)==null){
				throw new Error("target参数应为:Sprite或Shape实例及其子类实例.");
			}
			target.graphics.clear();
			if(width==0||height==0){
				return;
			}
			
			target.graphics.lineStyle(thickness,color,0,false,"none");
			if(filled)
				target.graphics.beginFill(color,alpha);
			target.graphics.drawRoundRect(x,y,width,height,round,round);
			target.graphics.endFill();
		}
	}
}